package com.rhino.security.service.impl;


import com.rhino.security.service.RefreshJWTTokenService;
import com.rhino.security.utils.JwtTokenUtil;
import com.rhino.security.vo.JWTTokenVO;
import com.rhino.security.vo.JwtUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;


/**
 * 刷新token的service接口实现类
 */
@Service
public class RefreshJWTTokenServiceImpl implements RefreshJWTTokenService {


    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public JWTTokenVO refreshToken(String refreshToken) {

        if (StringUtils.isBlank(refreshToken)) {
           throw new IllegalArgumentException("refreshToken is null");
        }

        Claims claimsFromToken = null;
        try {
            claimsFromToken = jwtTokenUtil.getClaimsFromToken(refreshToken);
        } catch (Exception exception) {
            if (exception instanceof ExpiredJwtException) {
                throw new IllegalArgumentException("认证失败，请重新登录");
            }
        }

        if (claimsFromToken == null) {
            throw new IllegalArgumentException("refreshToken is null");
        }
        Boolean tokenExpired = jwtTokenUtil.isTokenExpired(claimsFromToken);
        if (tokenExpired) {
            throw new IllegalArgumentException("refreshToken 已过期，请重新登录");
        }

        String userName = claimsFromToken.getSubject();
        return getTokenByUserName(userName);
    }

    @Override
    public JWTTokenVO getTokenByUserName(String userName) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
        if (StringUtils.isBlank(userName) || userDetails == null) {
            throw new IllegalArgumentException("获取用户信息失败！");
        }
        // 创建vo
        JWTTokenVO jwtToken = jwtTokenUtil.getJWTToken((JwtUser) userDetails);
        return jwtToken;
    }
}
